/*
 *
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Raúl Román López <rroman@gsyc.es>
 *
 */

package com.LibreGeoSocial.App.OMF;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

/**  
 *     
 * @author   
 */  
public class LocalizameAPI {	           
	/**  
     * URL of HTTP server which receives the login request  
     */  
    public static final String  TargetURLLogin = "https://www.localizame.movistar.es/login.do";   
    
    /**  
     * URL of HTTP server which receives the new user request 
     */
    public static final String  URLNewUser = "https://www.localizame.movistar.es/nuevousuario.do";   
    
    /**  
     * URL of HTTP server which receives the search request 
     */
    public static final String  URLSearch =  "https://www.localizame.movistar.es/buscar.do";    
    
    /**  
     * URL of HTTP server which receives the new locator request 
     */
    public static final String  URLNewLocator = "https://www.localizame.movistar.es/insertalocalizador.do";   
    
    /**  
     * URL of HTTP server which receives the erase locator request 
     */
    public static final String  URLEraseLocator = "https://www.localizame.movistar.es/borralocalizador.do";   
    
    /**  
     * URL of HTTP server which receives the logout request 
     */
    public static final String  URLLogout = "https://www.localizame.movistar.es/logout.do"; 
    
    
	private String login = null;
	private String pwd = null;
	private String sCookie = null;
         
	public boolean login (String login, String pwd) {
    	this.login = login;
		this.pwd = pwd;
    	
		URL url;
		HttpsURLConnection urlConn;
  
        boolean ret;
        
        try {
			url = new URL(LocalizameAPI.TargetURLLogin);
			
			urlConn = (HttpsURLConnection) url.openConnection();
			urlConn.setHostnameVerifier(new HostnameVerifier(){
				public boolean verify(String hostname, SSLSession session){
					return true;
				}
			});
			// set Post method
	        urlConn.setDoOutput (true);
	        
	        // setting headers
	        urlConn.setRequestMethod("POST");
	        urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
	        urlConn.setRequestProperty("Host", "www.localizame.movistar.es");
	        urlConn.setRequestProperty("Accept-Encoding", "identity");
	        urlConn.setRequestProperty("Accept-Language", "es");
	        urlConn.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*"); 
	        urlConn.setRequestProperty("Connection", "Keep-Alive");
	        urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)");
	        
	        // making content
	        String data = "usuario=" + this.login + 
	        				"&clave="+ this.pwd +
	        				"&submit.x=36" +
	        				"&submit.y=6";
	        
	        // writing content
			OutputStreamWriter out = new OutputStreamWriter(urlConn.getOutputStream());
			out.write (data);
			out.flush();
	        
			// getting response
			
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							urlConn.getInputStream()));
			
			List<String> cookies = urlConn.getHeaderFields().get("set-cookie");
			String sCookie = null;
			
			for (int i = 0; i<cookies.size(); i++){
				sCookie = cookies.get(i);
			}
			this.sCookie = sCookie;
			ret = newUser();
			
			out.close();
			in.close();
			
		} catch (MalformedURLException e) {
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
		}
        
        // devuelve true si login y password son correctos
        return ret;
    }

    public boolean newUser() {
    	
		URL url;
		HttpsURLConnection urlConn;
  
        boolean ret = true;
        
        try {
			url = new URL(LocalizameAPI.URLNewUser);
			
			urlConn = (HttpsURLConnection) url.openConnection();
			urlConn.setHostnameVerifier(new HostnameVerifier(){
				public boolean verify(String hostname, SSLSession session){
					return true;
				}
			});
			// set GET method
	        urlConn.setDoOutput (false);
	        urlConn.setRequestMethod("GET");
	        
	        // setting headers
	        urlConn.setRequestProperty("Accept-Language", "es");
	        urlConn.setRequestProperty("Host", "www.localizame.movistar.es");
	        urlConn.setRequestProperty("Accept-Encoding", "identity");
	        urlConn.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*"); 
	        urlConn.setRequestProperty("Connection", "Keep-Alive");
	        urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)");
	        urlConn.setRequestProperty("Referer", LocalizameAPI.TargetURLLogin);
	        urlConn.setRequestProperty("Cookie", this.sCookie);
			// getting response
			
	        if (urlConn.getResponseCode()!=200)
	        	return false;
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							urlConn.getInputStream()));
						
			in.close();
			
		} catch (MalformedURLException e) {
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
		}
        
        // devuelve true si login y password son correctos
        return ret;
    	
	}
    
    public double[] locate (String sTelefono) {
    	
    	URL url;
		HttpsURLConnection urlConn;
		double location[];
          
        try {
			url = new URL(LocalizameAPI.URLSearch);
			
			urlConn = (HttpsURLConnection) url.openConnection();
			urlConn.setHostnameVerifier(new HostnameVerifier(){
				public boolean verify(String hostname, SSLSession session){
					return true;
				}
			});
	        
			// set Post method
	        urlConn.setDoOutput (true);
	        urlConn.setRequestMethod("POST");
	        
	        // setting headers
	        urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
	        urlConn.setRequestProperty("Host", "www.localizame.movistar.es");
	        urlConn.setRequestProperty("Accept-Encoding", "identity");
	        urlConn.setRequestProperty("Accept-Language", "es");
	        urlConn.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*"); 
	        urlConn.setRequestProperty("Connection", "Keep-Alive");
	        urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)");
	        urlConn.setRequestProperty("Cookie", this.sCookie);
	        // making content
	        
	        String data = "telefono=" + sTelefono;
	        
	        // writing content
			OutputStreamWriter out = new OutputStreamWriter(urlConn.getOutputStream());
			out.write (data);
			out.flush();
	        
			// getting response
			
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							urlConn.getInputStream()));
			
			String response = "";
			String line;
			while ((line = in.readLine())!=null){
				response += line;
			}
			
			/*
			Integer iInicioRes = respuesta.indexOf(sTelefono);
        	Integer iFinRes = respuesta.indexOf("metros",iInicioRes);
        	// recupera el texto
        	if((iInicioRes > 0) && (iFinRes>0)) {
        		location = respuesta.substring(iInicioRes, iFinRes);
        		//System.out.println("Encontrado?: " + localizacion);	
        	} else {
        		location = "The number has not been located.";
        		//System.out.println("The number has not been located.");
        	}
			*/
			location = locationXtractor(response);
			out.close();
			in.close();
			
		} catch (MalformedURLException e) {
			location = null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			location = null;
		}
        
        // devuelve true si login y password son correctos
        return location;
    }
    
    public boolean authorize(String sTelefono) {
    	
		URL url;
		HttpsURLConnection urlConn;
		String sUrl = LocalizameAPI.URLNewLocator + "?telefono=" + sTelefono + "&submit.x=40&submit.y=5";
  
        boolean ret = true;
        
        try {
			url = new URL(sUrl);
			
			urlConn = (HttpsURLConnection) url.openConnection();
			urlConn.setHostnameVerifier(new HostnameVerifier(){
				public boolean verify(String hostname, SSLSession session){
					return true;
				}
			});
			// set GET method
	        urlConn.setDoOutput (false);
	        urlConn.setRequestMethod("GET");
	        
	        // setting headers	        
	        urlConn.setRequestProperty("Accept-Language", "es");
	        urlConn.setRequestProperty("Host", "www.localizame.movistar.es");
	        urlConn.setRequestProperty("Accept-Encoding", "identity");
	        urlConn.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*"); 
	        urlConn.setRequestProperty("Connection", "Keep-Alive");
	        urlConn.setRequestProperty("Referer", "http://www.localizame.movistar.es/buscalocalizadorespermisos.do");
	        urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)");
	        urlConn.setRequestProperty("Cookie", this.sCookie);
			// getting response
			
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							urlConn.getInputStream()));
			
			in.close();
			
		} catch (MalformedURLException e) {
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
		}
        
        // devuelve true si login y password son correctos
        return ret;
	}
    
    public boolean forbid(String sTelefono) {
    	

		URL url;
		HttpsURLConnection urlConn;
        String sUrl = LocalizameAPI.URLEraseLocator + "?telefono=" + sTelefono + "&submit.x=44&submit.y=8";
  
        boolean ret = true;
        
        try {
			url = new URL(sUrl);
			
			urlConn = (HttpsURLConnection) url.openConnection();
			urlConn.setHostnameVerifier(new HostnameVerifier(){
				public boolean verify(String hostname, SSLSession session){
					return true;
				}
			});
			// set GET method
	        urlConn.setDoOutput (false);
	        urlConn.setRequestMethod("GET");
	        
	        // setting headers	       
	        urlConn.setRequestProperty("Accept-Language", "es");
            urlConn.setRequestProperty("Host", "www.localizame.movistar.es");
            urlConn.setRequestProperty("Accept-Encoding", "identity");
            urlConn.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*"); 
            urlConn.setRequestProperty("Connection", "Keep-Alive");
            urlConn.setRequestProperty("Referer", "http://www.localizame.movistar.es/login.do");
            urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)");
	        urlConn.setRequestProperty("Cookie", this.sCookie);
			// getting response
			
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							urlConn.getInputStream()));
			
			in.close();
			
		} catch (MalformedURLException e) {
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
		}
        
        // devuelve true si login y password son correctos
        return ret;

	}
    
    public boolean logout() {
    	
		URL url;
		HttpsURLConnection urlConn;
  
        boolean ret = true;
        
        try {
			url = new URL(LocalizameAPI.URLLogout);
			
			urlConn = (HttpsURLConnection) url.openConnection();
			urlConn.setHostnameVerifier(new HostnameVerifier(){
				public boolean verify(String hostname, SSLSession session){
					return true;
				}
			});
			// set GET method
	        urlConn.setDoOutput (false);
	        urlConn.setRequestMethod("GET");
	        
	        // setting headers
	        urlConn.setRequestProperty("Accept-Language", "es");
	        urlConn.setRequestProperty("Host", "www.localizame.movistar.es");
	        urlConn.setRequestProperty("Accept-Encoding", "identity");
	        urlConn.setRequestProperty("Accept", "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*"); 
	        urlConn.setRequestProperty("Connection", "Keep-Alive");
	        urlConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)");
	        urlConn.setRequestProperty("Cookie", this.sCookie);	        
			// getting response
			
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							urlConn.getInputStream()));
			
			in.close();
			
			
		} catch (MalformedURLException e) {
			ret = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			ret = false;
		}
        
        // devuelve true si login y password son correctos
        return ret;
	}

    private double[] locationXtractor(String data){
    	double coords[] = new double[2], rad;
    	
    	//extracting latitude and longitude
    	try{
    		coords = coordXtractor(data.split("IFRAME")[1].split("\\?")[1]);
    	}catch(IndexOutOfBoundsException e){
    		return null;
    	}
    	if(coords==null)
    		return null;
    	
    	//Extracting radius
    	rad = Double.parseDouble(data.split("\\+\\/-")[1].split(" ")[1]);
    	if (data.split("\\+\\/-")[1].split(" ")[2].toUpperCase().equals("KILOMETROS\\."))
    		rad*=1000;
    	
    	double location[] = {coords[0], coords[1], rad};
    	
    	return location;
    }
    
    private double[] coordXtractor(String data){
    	double[] ret = new double[2];
    	String[] tuple = new String[2];
    	double X=0, Y=0;
    	
    	if(data.equals(""))
    		return null;
    	String[] tuples = data.split("&");
    	for(int i=0;i<tuples.length;i++){
    		tuple = tuples[i].split("=");
    		if(tuple[0].equals("X"))
    			X=Integer.parseInt(tuple[1]);
    		if(tuple[0].equals("Y"))
    			Y = Integer.parseInt(tuple[1]);
    	}
    	if (X==0 || Y==0)
    		return null;
    	
    	ret = UTM2geo(X, Y, 30);
    	
    	return ret;
    }
    /**
	 * Approaching by Hayford's ellipsoid. Northern Hemisphere.
	 * Return => [latitude, longitude]
	 */
    private double[] UTM2geo(double X1, double Y1, int zone){
    	
    	//previous steps
    	double X = X1;
    	double Y = Y1;
    	double a=6378388.0;
    	double b=6356911.946130;
    	double e2=(Math.sqrt(Math.pow(a,2)-Math.pow(b,2)))/b;
    	double e22=Math.pow(e2,2);
    	double c=Math.pow(a,2)/b;
    	
    	X=X-500000;
    	
    	double lambda_0=zone*6-183;

    	//Coticchia-Surace's equations
    	double sigma=Y/(6366197.724*0.9996);
    	double v=c*0.9996/Math.sqrt(1+e22*Math.pow(Math.cos(sigma),2));
    	a=X/v;
    	double A1=Math.sin(2*sigma);
    	double A2=A1*Math.pow(Math.cos(sigma),2);
    	double J2=sigma+A1/2.0;
    	double J4=(3*J2+A2)/4.0;
    	double J6=(5*J4+A2*Math.pow(Math.cos(sigma),2))/3.0;
    	double alpha=3*e22/4.0;
    	double beta=5/3.0*Math.pow(alpha,2);
    	double gamma=35/27.0*Math.pow(alpha,3);
    	double B=0.9996*c*(sigma-alpha*J2+beta*J4-gamma*J6);
    	b=(Y-B)/v;
    	double dseta=(e22*Math.pow(a*Math.cos(sigma),2))/2.0;
    	double xi=a*(1-dseta/3.0);
    	double eta=b*(1-dseta)+sigma;
    	double senhxi=(Math.pow(Math.E, xi)-Math.pow(Math.E, -xi))/2.0;
    	double inclambda=Math.atan(senhxi/Math.cos(eta));
    	double tau=Math.atan(Math.cos(inclambda)*Math.tan(eta));
    	
    	//calculating coordinates
    	double lng=inclambda*180/Math.PI+lambda_0;
    	
    	double lat=(sigma+(1+e22*Math.pow(Math.cos(sigma),2)-3.0/2.0*e22*Math.sin(sigma)*
    			Math.cos(sigma)*(tau-sigma))*(tau-sigma))*180/Math.PI;
    	
    	double[] ret = {lat, lng};
    	
    	return ret;
    }
}
